package org.dromara.hotel.dubbo;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.hotel.domain.bo.TerPriceCalendarBo;
import org.dromara.hotel.domain.vo.TerPriceCalendarVo;
import org.dromara.hotel.mapper.TerPriceCalendarMapper;
import org.dromara.hotel.service.ITerPriceCalendarService;
import org.dromara.tearoom.api.RemoteFullSyncService;
import org.redisson.api.RBatch;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
@DubboService
public class RemoteFullSyncServiceImpl implements RemoteFullSyncService {

    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
    private final TerPriceCalendarMapper  terPriceCalendarMapper;
    private static final String INVENTORY_KEY = "hotel:inventory:{roomTypeId}:{date}";
    private final RedisTemplate<String, String> redisTemplate;
    @Override
    public void scheduleFullSync() {
        RLock lock = CLIENT.getLock("inventory:full-sync:lock");
        try {
            if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
                syncAllInventory();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }

    @Async
    public void syncAllInventory() {
        List<TerPriceCalendarVo> inventoryList = terPriceCalendarMapper.selectVoList();
        if (CollectionUtils.isEmpty(inventoryList)) return;

        inventoryList.forEach(av -> {
            String key = buildInventoryKey(av.getRoomId(), av.getPriceDay());
            redisTemplate.opsForValue().set(key, String.valueOf(av.getAvailableQuantity()));
        });
    }

    public String buildInventoryKey(Long roomTypeId, LocalDate date) {
        return INVENTORY_KEY
            .replace("{roomTypeId}", roomTypeId.toString())
            .replace("{date}", date.toString());
    }
}
